<!-- CREATE 2022-08-15 -->
<!-- AUTHOR 伊玖OneNine -->

<script setup lang="ts">
import { AddOutline } from '@vicons/ionicons5'
import type { UploadCustomRequestOptions, UploadFileInfo } from 'naive-ui'
import type { FaceInfoType } from '~/api/face/faceType'

// *********
// 声明功能
// *********
const message = useMessage()
const loadingBar = useLoadingBar()

// *********
// 声明变量
// *********
const isAdd = ref(false)
const showModal = ref(false)
const modalLoading = ref(false)
const modalTitle = ref('')
const dataRef = ref<FaceInfoType[]>([])
const editData = ref<FaceInfoType>({
  id: -1,
  image: '',
  name: '',
  studentId: '',
})

// *********
// 计算属性
// *********
const AddTitle = computed(() => {
  return isAdd.value ? '请上传头像' : '加载中'
})

const ModelTitle = computed(() => {
  return isAdd.value ? '添加' : '编辑'
})

// *********
// 函数
// *********
// 清空编辑数组
function clearEditData() {
  editData.value = {
    id: -1,
    image: '',
    name: '',
    studentId: '',
  }
}

// 显示添加列表
function addTable() {
  clearEditData()
  modalTitle.value = '添加人脸信息'
  isAdd.value = true
  showModal.value = true
}

// 提交添加或编辑
function AddOrEdit() {
  if (isAdd.value)
    handleAddFaceInfo()
  else
    handleEditFaceInfo()
}

// 显示编辑
async function handleEdit(id: number) {
  clearEditData()
  isAdd.value = false
  const { code, data, msg } = await GetFaceInfo(id)

  if (code === OK_CODE) {
    editData.value = data
    modalTitle.value = `编辑 ${data.name}`
    showModal.value = true
  }
  else {
    message.error(msg)
  }
}

// 对上传图片进行筛选
async function beforeUpload(data: {
  file: UploadFileInfo
  fileList: UploadFileInfo[]
}) {
  const ftype = data.file.file?.type
  if (ftype === 'image/png' || ftype === 'image/jpeg')
    return true

  message.error('只能上传png格式的图片文件，请重新上传')
  return false
}

// 自定义上传
async function customRequest({ file, onFinish, onError }: UploadCustomRequestOptions) {
  const image = file.file as File
  if ((image.type === 'image/png') || (image.type === 'image/jpeg')) {
    const reander = new FileReader()
    reander.readAsDataURL(image)
    reander.onload = function () {
      editData.value.image = reander.result!.toString()
    }
    modalLoading.value = false
    onFinish()
  }
  else {
    modalLoading.value = false
    onError()
  }
}

// 添加人脸信息
async function handleAddFaceInfo() {
  loadingBar.start()

  const { code, msg } = await AddFaceInfo({
    image: editData.value.image,
    name: editData.value.name,
    studentId: editData.value.studentId,
  })

  if (code === OK_CODE) {
    loadingBar.finish()
    message.success(msg)
    showModal.value = false
    handleGetFaceInfo()
  }
  else {
    loadingBar.error()
    message.error(msg)
  }

  showModal.value = false
}

// 更新人脸信息
async function handleEditFaceInfo() {
  loadingBar.start()

  const { code, msg } = await UpdateFaceInfo(editData.value)
  if (code === OK_CODE) {
    loadingBar.finish()
    message.success(msg)
    showModal.value = false
    handleGetFaceInfo()
  }
  else {
    loadingBar.error()
    message.error(msg)
  }

  showModal.value = false
}

// 查询所有人脸信息
async function handleGetFaceInfo() {
  const { code, data, msg } = await GetAllFaceInfos()

  if (code === OK_CODE)
    dataRef.value = data
  else
    message.error(msg)
}

onMounted(() => {
  handleGetFaceInfo()
})

// 给子孙组件传参
provide('handleEdit', handleEdit)
provide('handleGetFaceInfo', handleGetFaceInfo)
</script>

<template>
  <n-card :bordered="false">
    <face-infos-table :table-data="dataRef">
      <template #tableTitle>
        <n-button type="primary" @click="addTable">
          <template #icon>
            <n-icon>
              <AddOutline />
            </n-icon>
          </template>
          新建
        </n-button>
      </template>
    </face-infos-table>

    <n-modal v-model:show="showModal" preset="dialog" title="Dialog">
      <template #header>
        <div>{{ modalTitle }}</div>
      </template>

      <n-form ref="formRef" :model="editData">
        <n-form-item label="头像" path="image">
          <div id="image-scroll-container">
            <n-image width="200" height="200" lazy :src="editData.image" :intersection-observer-options="{ root: '#image-scroll-container' }">
              <template #placeholder>
                <div class="image-loading">
                  {{ AddTitle }}
                </div>
              </template>
            </n-image>
          </div>
        </n-form-item>
        <n-form-item label="姓名" path="name">
          <n-input v-model:value="editData.name" placeholder="输入姓名" />
        </n-form-item>
        <n-form-item label="学号" path="studentId">
          <n-input v-model:value="editData.studentId" placeholder="输入学号" />
        </n-form-item>
      </n-form>

      <template #action>
        <n-upload
          accept="image/png, image/jpeg"
          :max="1"
          :show-file-list="false"
          :custom-request="customRequest"
          @before-upload="beforeUpload"
        >
          <n-button>上传头像</n-button>
        </n-upload>
        <n-button type="success" :loading="modalLoading" @click="AddOrEdit">
          {{ ModelTitle }}
        </n-button>
      </template>
    </n-modal>
  </n-card>
</template>

<style scoped>
#image-scroll-container {
  overflow: hidden;
  height: 200px;
  display: flex;
  flex-direction: column;
  gap: 8px;
  margin: 0 auto;
}
.image-loading {
  width: 200px;
  height: 200px;
  display: flex;
  align-items: center;
  justify-content: center;
  background-color: #0001;
}
</style>

<route lang="yaml">
meta:
  layout: default
</route>
